/* $Header: ramp_util.c,v 2.2 01/10/02 10:32:29 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1992                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:  ramp_util.c                                           */
/* ============                                                        */
/*                                                                     */
/* Author:                                                             */
/*                                                                     */
/* MODULE PURPOSE:                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/

#include <typedefs.h>
#include <p_wkfile.h>
#include <wkfile.h>
#include <ramps.h>
#include <zone_config.h>
#include <zone_status.h>
#include <status.h>
#include <i_op.h>


/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/


/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


U_INT32  Run_Length;           /* Total run length for current run.      */
U_INT32  Next_Run_Length;      /* Total run length for next run.         */

/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/

/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

#define RATE_TO_TIME 15625

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/

/***********************************************************************/
/* FUNCTION:  CalcRampLeft                                             */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To calculate the remaining time left in a single ramp.    */
/*                                                                     */
/* RETURNED VALUE:  U_INT32 in milliseconds                            */
/*                                                                     */
/* GLOBALS USED:  none                                                 */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

static U_INT32 CalcRampLeft( U_INT32 start_temp, U_INT32 final_value,
                             U_INT32 rate )
{
   INT32       delta_temp;

   /* Calculate difference between start temp and end temp */
   delta_temp = final_value - start_temp;

   /* Take into account possible negative ramps */
   if ( delta_temp < 0 )
   {
      delta_temp = -1*delta_temp;
   }

   /* Calculate time to ramp    */
   /* rate: degrees/(1000*min)  */
   /* delta temp: 1/64th degree */
   /* delta time: msec          */

   return ( ( (U_INT32)delta_temp * RATE_TO_TIME )/rate )*60;

}


/***********************************************************************/
/* FUNCTION:  CalcRampsLength                                          */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  Calculate the total time from the start of a ramp to      */
/*           the end of a profile.                                     */
/*                                                                     */
/* RETURNED VALUE:  U_INT32 length in milliseconds                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/* CALLS:                                                              */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

static U_INT32 CalcRampsLength( RAMPINFO  *info, U_INT8 i, U_INT32 start_temp )
{
   INT32       delta_temp;
   U_INT32     run_length;

   run_length = 0;

   while ( i < OVEN_RAMP_LEVELS )
   {
      if ( info->ramps[i].rate != 0 )
      {
         /* Calculate difference between start temp and end temp */
         delta_temp = info->ramps[i].final_value - start_temp;

         /* Take into account possible negative ramps */
         if ( delta_temp < 0 )
         {
            delta_temp = -1*delta_temp;
         }

         /* Calculate time to ramp    */
         /* rate: degrees/(1000*min)  */
         /* delta temp: 1/64th degree */
         /* delta time: msec          */

         run_length += ( ( (U_INT32)delta_temp * RATE_TO_TIME )/info->ramps[i].rate )*60;

         /* Add final time */
         run_length += info->ramps[i].final_time;

         /* Check for overflow.  We will not allow a run length over MAX */
         if ( run_length > MAX_RUN_TIME )
         {
            run_length = MAX_RUN_TIME;
            i = OVEN_RAMP_LEVELS;             /* terminate the loop */
         }

         /* Make new start temp previous end temp */
         start_temp = info->ramps[i].final_value;
      }
      else
      {
         i = OVEN_RAMP_LEVELS;
      }
      i++;
   }

   return run_length;
}

/***********************************************************************/
/* FUNCTION:  CalcRunLength                                            */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  To calculate the total run length based upon the oven     */
/*           temperature program setpoints.                            */
/*                                                                     */
/* RETURNED VALUE:  none                                               */
/*                                                                     */
/* GLOBALS USED:  Oven_Temp_Info: temp program setpoints               */
/*                                                                     */
/* CALLS:  CalcRampsLength, CalcRampLeft                               */
/*                                                                     */
/* LIMITATIONS:                                                        */
/*                                                                     */
/***********************************************************************/

void CalcRunLength( void )
{
   U_INT32   run_length, run_clock, setpoint, final_value, rate;
   INT32     temp;
   U_INT8    ramp_num;
   RAMPINFO  *info;

   info = &Oven_Temp_Info;

   /* Calculate run length in milliseconds */
   run_length = info->ramp_table->init_time;

   /* Check for special case of init time of zero and no first ramp.  */
   /* In this case we will set the run length to its maximum.         */
   if ( ( run_length == 0 ) && ( info->ramps[0].rate == 0 ) )
   {
      run_length = MAX_RUN_TIME;
   }
   else
   {
      run_length += CalcRampsLength( info, 0, info->ramp_table->init_value );

      /* Clamp at max run length */
      if ( run_length > MAX_RUN_TIME )
      {
         run_length = MAX_RUN_TIME;
      }
   }

   Next_Run_Length = run_length;

   /* Now see if we are in a run.  In this case we will calculate the run length as follows:  */
   /* add calculated time remaining to present run length.                                    */

   if ( Run_State == RUN_ACTIVE )
   {
      INTERRUPTS_OFF
         run_length  = Run_Clock;
         run_clock   = Run_Clock;
         setpoint    = *(info->setpoint);
         ramp_num    = info->ramp_num;
         rate        = info->ramps[ ramp_num ].rate;
         final_value = info->ramps[ ramp_num ].final_value;
      INTERRUPTS_ON

      switch ( info->ramp_state )
      {
         case INITIAL:  /* Get the time remaining in the initial time */
                        temp = info->ramp_table->init_time - run_clock;
                        run_length = (temp > 0) ? ( run_length + temp ) : run_length;
                        break;

         case FINAL:    /* Get the time remaining in the final time */
                        temp = info->ramps[ ramp_num ].final_time -
                               ( run_clock - info->check_time );
                        run_length = (temp > 0) ? ( run_length + temp ) : run_length;
                        ramp_num++;
                        break;

         case RAMP:     /* Check for being in a ramp and having a rate of 0 */
                        if ( info->ramps[ ramp_num ].rate == 0 )
                        {
                           run_length = MAX_RUN_TIME;
                        }
                        else
                        {
                           run_length += CalcRampLeft( setpoint, final_value, rate );

                           run_length += info->ramps[ ramp_num ].final_time;
                           setpoint = final_value;
                           ramp_num++;
                        }
                        break;
      }

      /* Now calculate the rest of the program, if any */
      if ( run_length < MAX_RUN_TIME )
      {
         run_length += CalcRampsLength( info, ramp_num, setpoint );
      }

      /* Clamp the length at MAX_RUN_TIME */
      if ( run_length > MAX_RUN_TIME ) run_length = MAX_RUN_TIME;

      /* Assign the run length for present run */
      Run_Length = run_length;

   }
   else
   {
      Run_Length = Next_Run_Length;
   }
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

void SetRampSetptPointer( pRAMPINFO rampinfo, INT32 *ptr )
{
     rampinfo->setpoint = (U_INT32 *)ptr;
}

U_INT32 GetRampInitTime( pRAMPINFO rampinfo )
{
    return rampinfo->ramp_table->init_time;
}

U_INT32 GetRampInitValue( pRAMPINFO rampinfo )
{
    return rampinfo->ramp_table->init_value;
}

U_INT32 GetRampRate( pRAMPINFO rampinfo, U_INT8 ramp_num )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num > (rampinfo->num_ramps ))
    {
         return 0;
    }
    else
    {
         return rampinfo->ramps[ramp_num-1].rate;
    }
}

U_INT32 GetRampFinalTime( pRAMPINFO rampinfo, U_INT8 ramp_num )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num > (rampinfo->num_ramps))
    {
         return 0;
    }
    else
    {
         return rampinfo->ramps[ramp_num-1].final_time;
    }
}

U_INT32 GetRampFinalValue( pRAMPINFO rampinfo, U_INT8 ramp_num )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num > (rampinfo->num_ramps))
    {
         return 0;
    }
    else
    {
         return rampinfo->ramps[ramp_num-1].final_value;
    }
}

U_INT32 GetRampPostValue( pRAMPINFO rampinfo )
{
     return rampinfo->ramp_table->post_value;
}


RAMP_TYPE GetRampType( pRAMPINFO rampinfo )
{
     return rampinfo->ramp_table->ramp_type;
}

RAMP_FLAG GetRampState( pRAMPINFO rampinfo )
{

     return rampinfo->ramp_state;
}



/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

void DisableRamp( pRAMPINFO rampinfo )
{
    rampinfo->ramp_enabled = FALSE;
}

void EnableRamp( pRAMPINFO rampinfo )
{
    rampinfo->ramp_enabled = TRUE;
}

void SetRampInitTime( pRAMPINFO rampinfo, U_INT32 init_time )
{
    rampinfo->ramp_table->init_time = init_time;
}

void SetRampInitValue( pRAMPINFO rampinfo, U_INT32 init_value )
{
    rampinfo->ramp_table->init_value = init_value;
}

void SetRampRate( pRAMPINFO rampinfo, U_INT8 ramp_num, U_INT32 rate )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num <= (rampinfo->num_ramps))
    {
         rampinfo->ramps[ramp_num-1].rate = rate;
    }
}

void SetRampFinalTime( pRAMPINFO rampinfo, U_INT8 ramp_num, U_INT32 final_time )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num <= (rampinfo->num_ramps))
    {
         rampinfo->ramps[ramp_num-1].final_time = final_time;
    }
}

void SetRampFinalValue( pRAMPINFO rampinfo, U_INT8 ramp_num, U_INT32 final_value )
{
     /* ramp_num = 1..RAMP_LEVELS */
    if ( ramp_num <= (rampinfo->num_ramps))
    {
         rampinfo->ramps[ramp_num-1].final_value = final_value;
    }
}

void SetRampPostValue( pRAMPINFO rampinfo, U_INT32 post_value )
{
     rampinfo->ramp_table->post_value = post_value;
}

void SetRampType( pRAMPINFO rampinfo, RAMP_TYPE type )
{
     rampinfo->ramp_table->ramp_type = type;
}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

BIT8 RampInitialValueActive( pRAMPINFO rampinfo )
{
       return ( rampinfo->ramp_state == INITIAL );
}


U_INT8 GetCurrentOvenRampNum( void )
{
   U_INT8 ramp_num;

   INTERRUPTS_OFF
     ramp_num =  ((Oven_Temp_Info.ramp_state == RAMP  )  ||
                  (Oven_Temp_Info.ramp_state == FINAL ))  ? Oven_Temp_Info.ramp_num+1 : 0;
   INTERRUPTS_ON

   return ramp_num;
}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

pRAMPINFO pOvenRamp(void)
{
    return &Oven_Temp_Info;
}

pRAMPINFO pInjaRamp(void)
{
    return &Inja_Temp_Info;
}

pRAMPINFO pInjbRamp(void)
{
    return &Injb_Temp_Info;
}

pRAMPINFO pDetaRamp(void)
{
    return &Deta_Temp_Info;
}

pRAMPINFO pDetbRamp(void)
{
    return &Detb_Temp_Info;
}

pRAMPINFO pAux1Ramp(void)
{
    return &Aux1_Temp_Info;
}

pRAMPINFO pAux2Ramp(void)
{
    return &Aux2_Temp_Info;
}

pRAMPINFO pCol1Ramp(void)
{
    return &Col1_Pres_Info;
}

pRAMPINFO pCol2Ramp(void)
{
    return &Col2_Pres_Info;
}

pRAMPINFO pAux3Ramp(void)
{
    return &Aux3_Pres_Info;
}

pRAMPINFO pAux4Ramp(void)
{
    return &Aux4_Pres_Info;
}

pRAMPINFO pAux5Ramp(void)
{
    return &Aux5_Pres_Info;
}

BIT8 RampPostValueActive(  )
{
       return ( pOvenRamp()->ramp_state == POST );
}

